/*
 * Created by SharpDevelop.
 * User: Oded Sharon
 * Date: 10-Oct-07
 * Time: 5:39 AM
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using System.Text;
using System.IO;
using System.ComponentModel;
using RegEdit;
using Microsoft.Win32;

namespace dialogmaker
{
	/// <summary>
	/// Description of MainForm.
	/// </summary>
	/// 
	
	
	public partial class MainForm : Form
	{
		private const int ENTRY_NOT_FOUND = -1;
		 // Registry root sub-key
        private static string REGISTRY_SUB_KEY = "SOFTWARE\\DEAD:CODE\\Wintermute Tools\\WmeDialogEditor";        
        private static string REG_KEY_WME_EXEC = "WME_EXE";
        private static string REG_KEY_WME_PROJECT = "WME_PROJECT_DIR";
        

		   
		   
		private Dialog.Dialog m_Dialog;
		private System.Collections.Hashtable m_ChoiceCollectionsTable;
		private System.Collections.Hashtable m_ChoicesTable;
		private System.Collections.Hashtable m_responsesTable;
		private int[] m_DialogChoicesIDs;
		private TextBox[] m_choiceboxes;
		private int m_LargestID;
		private bool m_DataLoaded;
		private bool m_DontUpdateTree;
		private string m_CurrentResponseID;
		private string NodeMap;
			
		public MainForm()
		{
			//
			// The InitializeComponent() call is required for Windows Forms designer support.
			//
			InitializeComponent();
			
			//
			// TODO: Add constructor code after the InitializeComponent() call.
			//
			
			NewTree();
		}
	
		void NewTree()
		{
			textBoxXMLFilePath.Text = "";
			SceneBox.Text = "";
			PlayerActorBox.Text = "";
			RespondingActorBox.Text = "";
			m_DialogChoicesIDs = new int[4];
			for (int i = 0; i < 4; i++)
				m_DialogChoicesIDs[i] = -1;
			
			m_LargestID = 0;
			m_DataLoaded = false;
			
			
			m_ChoiceCollectionsTable = new System.Collections.Hashtable();
			m_responsesTable = new System.Collections.Hashtable();
			m_ChoicesTable = new  System.Collections.Hashtable();
			
			m_Dialog = new Dialog.Dialog();
			
			m_DontUpdateTree = false;
			
			
			listView1.Items.Clear();
			listView1.View = View.List;
			listView1.LabelEdit = true;
			
			m_CurrentResponseID = "-1";
			
			InitTree();
		}
		
		void Button1Click(object sender, EventArgs e)
		{
			DialogResult dr = saveFileDialog1.ShowDialog();
            if (DialogResult.OK == dr)
            {            	
                    textBoxXMLFilePath.Text = saveFileDialog1.FileName;
                	SaveTree();                	
            }
			
		}
		
		void Button2Click(object sender, EventArgs e)
		{
			ConsolidateTree(null);
			InitTree();
		}
		
	  private void AddNode(XmlNode inXmlNode, TreeNode inTreeNode)
      {
         XmlNode xNode;
         TreeNode tNode;
         XmlNodeList nodeList;
         int i;

         // Loop through the XML nodes until the leaf is reached.
         // Add the nodes to the TreeView during the looping process.
         if (inXmlNode.HasChildNodes)
         {
            nodeList = inXmlNode.ChildNodes;
            for(i = 0; i<=nodeList.Count - 1; i++)
            {
               xNode = inXmlNode.ChildNodes[i];
               inTreeNode.Nodes.Add(new TreeNode(xNode.Name));
               tNode = inTreeNode.Nodes[i];               
               AddNode(xNode, tNode);
            }
         }
         else
         {
            // Here you need to pull the data from the XmlNode based on the
            // type of node, whether attribute values are required, and so forth.
            inTreeNode.Text = (inXmlNode.OuterXml).Trim();
         }
      }                  

	  
	  private void FillTree(Dialog.DialogChoiceCollection inDialog, TreeNode inTreeNode) 
	  {
	  		TreeNode tNode,tNode2;
	  		Dialog.DialogChoiceCollection.Enumerator dEnum;
			dEnum = inDialog.GetEnumerator();			
			dEnum.MoveNext();			
			string mytext;
			int m;
			
			for (int i=0; i< inDialog.Count && i<4;i++) {
	            	 mytext = dEnum.Current.SelectionString;
	            	 if (mytext == null || mytext == "")
	            	 	mytext = "<EMPTY>";
	            	 int n = inTreeNode.Nodes.Add(new TreeNode(mytext));
               		 tNode = inTreeNode.Nodes[n];
               		 //tNode. add ID or soemthing
               		 tNode.Name = dEnum.Current.ID.ToString();               		 
               		 tNode.ForeColor = Color.Green;
               		 
               		 m_ChoiceCollectionsTable.Add(dEnum.Current.ID.ToString(),dEnum.Current.DialogChoice1);
               		 m_ChoicesTable.Add(dEnum.Current.ID.ToString(),dEnum.Current);               		 
               		 m_responsesTable.Add(dEnum.Current.ID.ToString(),dEnum.Current.Response);
               		 
               		 if (m_LargestID < dEnum.Current.ID)
               		 	m_LargestID = dEnum.Current.ID;
               		 
               		 bool targetspec = false;
               		 
               		 bool BreakLoop = false;
               		 string targetID = "";
               		 foreach (Dialog.Response res in dEnum.Current.Response){
               		 	mytext = res.TalkString;
               		 	m = tNode.Nodes.Add(new TreeNode(mytext));
               		 	tNode2 = tNode.Nodes[m];
               		 	tNode2.ForeColor = Color.Blue;
               		 	tNode2.Name = dEnum.Current.ID.ToString();
               		 	
               		 	mytext = res.ResponseString;
               		 	m = tNode.Nodes.Add(new TreeNode(mytext));
               		 	tNode2 = tNode.Nodes[m];
               		 	tNode2.ForeColor = Color.Red;
               		 	tNode2.Name = dEnum.Current.ID.ToString();
               		 		
               		 	targetspec = res.TargetIDSpecified;
               		 	targetID = res.TargetID.ToString();
               		 	BreakLoop = res.BreakLoop;
               		 	
               		 	
               		 }
               		 
               		
               		 
               		 if (dEnum.Current.DialogChoice1.Count > 0)
               		 	FillTree(dEnum.Current.DialogChoice1, tNode);
               		 else {
               		  if (targetspec  == true){
               		 		mytext = "-> " + targetID;
	               		 	m = tNode.Nodes.Add(new TreeNode(mytext));
	               		 	tNode2 = tNode.Nodes[m];
	               		 	tNode2.ForeColor = Color.Purple;
	               		 	tNode2.Name = targetID;
               		 	
               		 	} else {
               		 		mytext = "<-";
	               		 	m = tNode.Nodes.Add(new TreeNode(mytext));
	               		 	tNode2 = tNode.Nodes[m];
	               		 	tNode2.ForeColor = Color.Purple;
	               		 	tNode2.Name = dEnum.Current.ID.ToString();
               		 		
               		 	}                		

               		 	if (BreakLoop  == true){
               		 		mytext = "X";
	               		 	m = tNode.Nodes.Add(new TreeNode(mytext));
	               		 	tNode2 = tNode.Nodes[m];
	               		 	tNode2.ForeColor = Color.Purple;
	               		 	tNode2.Name = targetID;
               		 	
               		 	}
               		 	if (dEnum.Current.Loop == true){
               		 		mytext = "<>";
	               		 	m = tNode.Nodes.Add(new TreeNode(mytext));
	               		 	tNode2 = tNode.Nodes[m];
	               		 	tNode2.ForeColor = Color.Purple;
	               		 	tNode2.Name = dEnum.Current.ID.ToString();
               		 	
               		 	}	
               		 	if (dEnum.Current.DisplayOnce == true){
               		 		mytext = "*";
	               		 	m = tNode.Nodes.Add(new TreeNode(mytext));
	               		 	tNode2 = tNode.Nodes[m];
	               		 	tNode2.ForeColor = Color.Purple;
	               		 	tNode2.Name = dEnum.Current.ID.ToString();
               		 	
               		 	}	
               		 }
               		 
               		 
					 dEnum.MoveNext();
				
			     }
	  }
		
	  
	  void ConsolidateTree(Dialog.DialogChoice inChoice)
	  {
	  	Dialog.DialogChoiceCollection inChoiceCol;
	  	if (inChoice == null) {
	  		inChoiceCol = m_Dialog.DialogTree;	
	  	} else {
	  		inChoiceCol = inChoice.DialogChoice1;
	  	}
	  	Dialog.DialogChoice[] removeChoices = new Dialog.DialogChoice[4];
	  	int max = 0;
	  	
	  	foreach (Dialog.DialogChoice choice in inChoiceCol)
	  	{
	  		if (choice.DialogChoice1.Count > 0)
	  			ConsolidateTree(choice);
	  		else if ((choice.SelectionString == "" || choice.SelectionString == null) &&	  		    
	  		    choice.Response.Count == 0)
	  			removeChoices[max++] = choice;
	  	}
	  	
	  	for (int i=0;i<max;i++) {
	  		if (removeChoices[i]!= null)
		  		inChoiceCol.Remove(removeChoices[i]);
	  	}
	  	
	  	
	  	
	  }
		void TreeChange(object sender, EventArgs e)
		{
			if (m_DontUpdateTree)
				return;
			
			TreeNode tNode = treeView1.SelectedNode;
			
			if (tNode == null)
				return;
			
			UpdateDialogFields(tNode.Name);
			
			if (tNode.Parent != null)
				fillListBox(tNode.Name,tNode.Parent.Name);
			else
				fillListBox(tNode.Name,"0");
		}
		
		void UpdateDialogFields(string id)
		{
			m_DataLoaded = false;
			
			listView1.Clear();
			
			Dialog.DialogChoiceCollection currentDialog;
			
			currentDialog= (Dialog.DialogChoiceCollection )m_ChoiceCollectionsTable[id];
			
			IDBox.Text = id;
			
			m_choiceboxes = new TextBox[4];
			m_choiceboxes[0] = ChoiceBox1;
			m_choiceboxes[1] = ChoiceBox2;
			m_choiceboxes[2] = ChoiceBox3;
			m_choiceboxes[3] = ChoiceBox4;
			
			Dialog.DialogChoiceCollection.Enumerator dEnum;
			dEnum = currentDialog.GetEnumerator();
			dEnum.Reset();
			string mytext;
			int tmpID;
			
			//mytext = dEnum.Current.SelectionString;
			dEnum.MoveNext();
			
			for (int i=0; i<4;i++) {	
				if (i< currentDialog.Count) {
					mytext = dEnum.Current.SelectionString;
					tmpID = dEnum.Current.ID;
					dEnum.MoveNext();
				} else {
					mytext ="";
					tmpID = -1;
				}
				m_choiceboxes[i].Text =  mytext;		
				m_DialogChoicesIDs[i] = tmpID;
			}	
			
			loopCheckBox.Enabled = currentDialog.Count > 0;
			if (id == "0" || id == "-1") {
				loopCheckBox.Checked = m_Dialog.Loop;
				checkBoxOnce.Enabled = false;
	
			} else {
				Dialog.DialogChoice CurrentChoice = (Dialog.DialogChoice)m_ChoicesTable[id];
				if (CurrentChoice  == null) {
					loopCheckBox.Enabled = false;
					checkBoxOnce.Enabled = false;					
				} else {
					loopCheckBox.Enabled = true;
					loopCheckBox.Checked = CurrentChoice.Loop;
					checkBoxOnce.Enabled = true;
					checkBoxOnce.Checked = CurrentChoice.DisplayOnce;
				}
								
			}
			
			
	
			TreeNode selected = treeView1.Nodes.Find(id,true)[0];
			treeView1.SelectedNode = selected;
			m_DataLoaded = true;
		}
		
		void focusChoice(int i) {
			
			listView1.Items.Clear();
			if (m_DialogChoicesIDs[i] < 0) {				
				return;
			}
				
			int id = m_DialogChoicesIDs[i];
			
			m_DontUpdateTree = true;
			
			TreeNode selected =treeView1.Nodes.Find(id.ToString(),true)[0];
			treeView1.SelectedNode = selected;
			m_DontUpdateTree = false;
			
			fillListBox(id.ToString(),IDBox.Text);
		}
		
		void fillListBox(string ID, string ParentID)
		{	
			
			listView1.Items.Clear();
			listView1.View = View.List;
			listView1.LabelEdit = true;

			
			Dialog.ResponseCollection responses = (Dialog.ResponseCollection)m_responsesTable[ID];
			if (responses == null) {
				if (m_CurrentResponseID != "-1")
					listView1.Items.Add("<NEW>");
				return;
			}


			// TODO : fix this code
			if (ParentID == "0") {
				breakLoopCheckBox.Enabled = m_Dialog.Loop;
			} else {
				Dialog.DialogChoice choice = (Dialog.DialogChoice)m_ChoicesTable[ParentID];
				breakLoopCheckBox.Enabled = choice.Loop;
			}
			
			bool BreakLoop=false;
			m_CurrentResponseID = ID;
			foreach (Dialog.Response res in responses) {
				
				ListViewItem tmpList = listView1.Items.Add(res.TalkString);
				tmpList.ForeColor = Color.Blue;

				tmpList = listView1.Items.Add(res.ResponseString);
				tmpList.ForeColor = Color.Red;	
				
				if (res.TargetIDSpecified) {
					TargetIDBox.Text = res.TargetID.ToString();
				} else {
					TargetIDBox.Text = "";
				}
				
				BreakLoop = res.BreakLoop;
				

			}
			
			breakLoopCheckBox.Checked = BreakLoop;
			
	
			
			listView1.Items.Add("<NEW>");
		}
		
		void ButtonStringTablePathClick(object sender, EventArgs e)
		{
			DialogResult dr = openFileDialogXMLFile.ShowDialog();
            if (DialogResult.OK == dr)
            {
            	if (openFileDialogXMLFile.CheckFileExists) {
                    textBoxXMLFilePath.Text = openFileDialogXMLFile.FileName;
                	LoadTree();                	
            	}
                else
                {
                    StringBuilder strError = new StringBuilder();
                    strError.AppendFormat("File {0} doesn't exist!", openFileDialogXMLFile.FileName);
                    MessageBox.Show(strError.ToString());
                }
            }
		}
		
		void SaveTree()
		{
			string xmldialogfilename =  textBoxXMLFilePath.Text;
			
			XmlDocument dialogXMLDoc = new XmlDocument();
			string xmlstr;
			xmlstr = Dialog.Serializer.ToXml(m_Dialog,typeof(Dialog.Dialog));
			dialogXMLDoc.LoadXml(xmlstr);
			dialogXMLDoc.Save(xmldialogfilename);
			
			toolStripStatusLabel1.Text = "Dialog tree XML file saved successfully...";
			
		}
		
		void LoadTree()
		{
			
			
			try {
				
			string xmldialogfilename =  textBoxXMLFilePath.Text;
			
			 		
			
			XmlDocument dialogXMLDoc = new XmlDocument();
			dialogXMLDoc.Load(xmldialogfilename);
			
			string xmlstr = dialogXMLDoc.InnerXml;
			m_Dialog = (Dialog.Dialog)Dialog.Serializer.FromXml(xmlstr,typeof(Dialog.Dialog));
			}
			   catch(Exception ex)
       		{
            MessageBox.Show(ex.Message);
        	}
			
			PlayerActorBox.Text = m_Dialog.PlayerActor;
			RespondingActorBox.Text = m_Dialog.RespondingActor;
			
			SceneBox.Text = m_Dialog.Scene;
			
	
			InitTree();
	
			toolStripStatusLabel1.Text = "Dialog tree XML file loaded successfully...";
		}
		
		void InitTree()
		{
			m_DataLoaded = false;
		// SECTION 2. Initialize the TreeView control.
			treeView1.Nodes.Clear();
			//treeView1.FullRowSelect = true;
			treeView1.HideSelection = false;		
			treeView1.ShowLines = true;
			treeView1.Nodes.Add(new TreeNode("Dialog"));
			treeView1.Nodes[0].Name = "0";
			
			//treeView1.HotTracking = true;
			//treeView1.FullRowSelect = true;

			
			m_ChoiceCollectionsTable = new System.Collections.Hashtable();
			m_responsesTable = new System.Collections.Hashtable();
			m_ChoicesTable = new  System.Collections.Hashtable();
			m_ChoiceCollectionsTable.Add("0",m_Dialog.DialogTree);
			
	   		UpdateDialogFields("0");
	   		
	   		FillTree(m_Dialog.DialogTree,  treeView1.Nodes[0]);
	   		
	   		treeView1.ExpandAll();
	   		
	   		m_DataLoaded = true;
			
		}

		void ChoiceboxTextChanges(int i)
		{
			if (!m_DataLoaded)
				return;
			int ID = m_DialogChoicesIDs[i];
			Dialog.DialogChoice dialogChoice= (Dialog.DialogChoice)m_ChoicesTable[ID.ToString()];
		
			if (ID < 0) {
				string ParentID = treeView1.SelectedNode.Name;
				Dialog.DialogChoiceCollection dialogChoiceCollection = (Dialog.DialogChoiceCollection)m_ChoiceCollectionsTable[ParentID];
				
				Dialog.DialogChoice newChoice;				
				TreeNode ParentNode = treeView1.Nodes.Find(ParentID,true)[0];
				while (dialogChoiceCollection.Count < i + 1) {
					newChoice = new Dialog.DialogChoice();
					ID = ++m_LargestID;				
					newChoice.ID =  ID;		
					m_DialogChoicesIDs[dialogChoiceCollection.Count] = ID;
					dialogChoiceCollection.Add(newChoice);
					m_ChoicesTable.Add(ID.ToString(),newChoice);
					m_ChoiceCollectionsTable.Add(ID.ToString(),newChoice.DialogChoice1);
					m_responsesTable.Add(ID.ToString(),newChoice.Response);
					dialogChoice = newChoice;	
					
					
					TreeNode tmpNode = ParentNode.Nodes.Add("<EMPTY>");					
					tmpNode.ForeColor = Color.Green;
					tmpNode.Name = ID.ToString();					
				}		
			}
				
			dialogChoice.SelectionString = m_choiceboxes[i].Text.ToString();
			treeView1.Nodes.Find(ID.ToString(),true)[0].Text = m_choiceboxes[i].Text.ToString();
		}
		
		void LoadStringTab(ref Hashtable  stringTabHash,ref ArrayList  strTabIdxes, string strTableFile)
		{
			
			stringTabHash = new Hashtable();
			strTabIdxes = new ArrayList();
			
			using (StreamReader sr = new StreamReader(strTableFile)) {
	            string strLine;
	            
	            while ((strLine = sr.ReadLine()) != null)
	            {
	            	string[] strArry = strLine.Split('\t');
	            	strTabIdxes.Add(strArry[0]);
	            	if (strArry.Length > 1)
	            		if (stringTabHash.Contains(strArry[0]))
		            		stringTabHash[strArry[0]] = strArry[1];
		            	else
		                   	stringTabHash.Add(strArry[0],strArry[1]);	            	
	            
	            }
			}
		}
		
		void AddToStringTab(Hashtable stringTabHash, ArrayList strTabIdxes, string idx, string value) 
		{
			if (!stringTabHash.Contains(idx)) {
				strTabIdxes.Add(idx);
				stringTabHash.Add(idx,value);
			} else {
				stringTabHash[idx] = value;
			}
			
			
			
		}
		
		void SaveStringTab(Hashtable stringTabHash, ArrayList strTabIdxes,string strTableFile )
		{
			
			using (StreamWriter sw = new StreamWriter(strTableFile, false))
			{
				foreach (string idx in strTabIdxes) {
					string output = idx + "\t" + ((string)stringTabHash[idx]);
					sw.WriteLine(output.ToString());
				}
            	
			}
			
		}
		
		void ExportToWME()
		{
			DialogResult dr = saveFileDialog2.ShowDialog();
            if (DialogResult.OK != dr)
            	return;
            dr = saveFileDialog3.ShowDialog();
            if (DialogResult.OK != dr)
            	return;
            string filename = saveFileDialog2.FileName;
            string strTableFile = saveFileDialog3.FileName;
            ExportToWME2(filename,strTableFile);
		}
		void ExportToWME2(string filename,string strTableFile)
		{            
        	StringBuilder output = new StringBuilder();
        	StringBuilder output2 = new StringBuilder();
        	//StringBuilder stringtab = new StringBuilder();
        	
        	System.Collections.Hashtable strtingTabHash = null;
        	ArrayList stringTabIDX = null;
        	
        	LoadStringTab(ref strtingTabHash,ref stringTabIDX,strTableFile);
        	
        	
        	output.AppendLine("#include \"scripts\\base.inc\"");
        	output.AppendLine("");
        	output.AppendFormat("global {0};",m_Dialog.PlayerActor);
        	output.AppendLine("");
        	output.AppendFormat("global {0};",m_Dialog.RespondingActor);
        	output.AppendLine("");
        	output.AppendLine("");
        	output.AppendLine("method RunDialog()\n{");
        	output.AppendLine("");
        	output.AppendLine("Game.Interactive = false;");
        	output.AppendLine("");
 
        	
        	AddDialogChoices(m_Dialog.DialogTree, m_Dialog.Loop, 0, output, output2, strtingTabHash,stringTabIDX);
        	
        	output.AppendLine("");
        	output.AppendLine("Game.Interactive = true;");
        	output.AppendLine("");
        	output.AppendLine("}");
        	output.AppendLine("");
        	
        	output.Append(output2);
            

        	//MessageBox.Show(output.ToString());
        	// Reinsert the updated data to the string table file
            using (StreamWriter sw = new StreamWriter(filename, false))
			{
            	sw.Write(output.ToString());
			}
			
        	try 
                {
        		/*
                    // Create an instance of StreamReader to read from a file.
                    // The using statement also closes the StreamReader.
                    ArrayList al = new ArrayList();
                    string strEntryKey = "";
                    int iEntryInd = ENTRY_NOT_FOUND;

                    // Read the entire string table, and remove all prior entries carrying same entry key
                    using (StreamReader sr = new StreamReader(strTableFile))
                    {
                        string strLine;
                        int iLine = 0;
                        while ((strLine = sr.ReadLine()) != null)
                        {
                            if ((ENTRY_NOT_FOUND == iEntryInd) && strLine.Contains(strEntryKey))
                                iEntryInd = iLine;
                            else
                                al.Add(strLine);
                            ++iLine;
                        }
                    }

                    // Update the string table data with the new table entry key and text
                    if (ENTRY_NOT_FOUND == iEntryInd)
                        iEntryInd = al.Add(stringtab.ToString());
                    else
                        al.Insert(iEntryInd, stringtab.ToString());

                    // Reinsert the updated data to the string table file
                    using (StreamWriter sw = new StreamWriter(strTableFile, false))
                    {
                        foreach(string strLine in al)
                            sw.WriteLine(strLine);
                    }

                    */
                   SaveStringTab(strtingTabHash, stringTabIDX,strTableFile);
                }
                catch (Exception excep) 
                {
                    // Let the user know what went wrong.
                    MessageBox.Show("The file could not be read:" + excep);
                }
                
                toolStripStatusLabel1.Text = "Dialog exported to WME files successfully...";
                
		}
		
		void AddDialogChoices(Dialog.DialogChoiceCollection inCollection, bool Loop,int ID, StringBuilder output1, StringBuilder output2, Hashtable stringTabHash, ArrayList strTabIdxes)
		{
			output2.AppendFormat("function RunDialog_{0:D2}()",ID);
			output2.AppendLine("");
			output2.AppendLine("{");
			output1.AppendFormat("\tRunDialog_{0:D2}(); ",ID);
			output1.AppendLine("");
						
			output2.AppendLine("\tvar Selected;");
			output2.AppendLine("\tvar SelectionLine;");
			
			if (Loop) {
				output2.AppendLine("\tvar inLoop = true;");
				output2.AppendLine("\twhile (inLoop) {");
			}

			
			output2.AppendFormat("\tGame.StartDlgBranch(\"DIALOG_{3}_{0}_{1}_{2:D2}\");",m_Dialog.PlayerActor,m_Dialog.RespondingActor,ID,m_Dialog.Scene);
			output2.AppendLine("");
			
			StringBuilder output3 = new StringBuilder();
			StringBuilder output5 = new StringBuilder();
			
			int i=0;
			foreach (Dialog.DialogChoice choice in inCollection) {
				
				StringBuilder tag = new StringBuilder();
				tag.AppendFormat("DIALOG_{3}_{0}_{1}_{2:D2}",m_Dialog.PlayerActor,m_Dialog.RespondingActor,choice.ID,m_Dialog.Scene);

				output2.AppendLine("");
				output2.Append("\t//");
				output2.AppendLine(choice.SelectionString);				
				output2.AppendFormat("\tSelectionLine = \"/{0}/MISSING TEXT {0}\";",tag.ToString());
				output2.AppendLine("");
				output2.AppendLine("\tGame.ExpandString(SelectionLine);");
				
				if (choice.DisplayOnce)
					output2.Append("\tGame.AddResponseOnceGame(");
				else 
					output2.Append("\tGame.AddResponse(");

				output2.AppendFormat("{0},SelectionLine);",i);
				output2.AppendLine("");
				
				AddToStringTab(stringTabHash,strTabIdxes,tag.ToString(),choice.SelectionString);
				//stringtab.AppendFormat("{0}\t{1}",tag.ToString(),choice.SelectionString);
				//stringtab.AppendLine("");
				
				output3.AppendFormat("\tcase {0}:",i);
				output3.AppendLine("");
				int j=0;
				bool breakLoop = false;
				foreach (Dialog.Response response in choice.Response) {
					output3.Append("\t\t//");
					output3.AppendLine(response.TalkString);
					output3.AppendFormat("\t\t{0}.Talk(\"/{1}_{2:D2}/MISSING TEXT{1}_{2:D2}\");",m_Dialog.PlayerActor,tag.ToString(),j);
					output3.AppendLine("");
					
					StringBuilder sbtmp = new StringBuilder();
					sbtmp.AppendFormat("{0}_{1:D2}",tag.ToString(),j);
					AddToStringTab(stringTabHash,strTabIdxes,sbtmp.ToString(),response.TalkString);
					//stringtab.AppendFormat("{0}_{1:D2}\t{2}",tag.ToString(),j,response.TalkString);
					//stringtab.AppendLine("");
					j++;
					StringBuilder tag2 = new StringBuilder();
					tag2.AppendFormat("DIALOG_{3}_{0}_{1}_{2:D2}",m_Dialog.RespondingActor,m_Dialog.PlayerActor,choice.ID,m_Dialog.Scene);
		
					output3.Append("\t\t//");
					output3.AppendLine(response.ResponseString);

					output3.AppendFormat("\t\t{0}.Talk(\"/{1}_{2:D2}/MISSING TEXT{1}_{2:D2}\");",m_Dialog.RespondingActor,tag2.ToString(),j);
					output3.AppendLine("");
					
					StringBuilder sbtmp2 = new StringBuilder();
					sbtmp2.AppendFormat("{0}_{1:D2}",tag2.ToString(),j);
					AddToStringTab(stringTabHash,strTabIdxes,sbtmp2.ToString(),response.ResponseString);
					
					//stringtab.AppendFormat("{0}_{1:D2}\t{2}",tag2.ToString(),j,response.ResponseString);
					//stringtab.AppendLine("");
					j++;

						
					if (response.BreakLoop) 
						breakLoop = true;
				}
				
				if (choice.DialogChoice1.Count > 0) {
						StringBuilder output4 = new StringBuilder();
						
						AddDialogChoices(choice.DialogChoice1,choice.Loop,choice.ID,output4,output5, stringTabHash,  strTabIdxes);
						output3.Append("\t");
						output3.Append(output4);
				}
	
				
				if (Loop && breakLoop)
					output3.AppendLine("\tinLoop = false;");
				
				output3.AppendLine("\tbreak;");
				i++;
			}
			
			
			
			output2.AppendFormat("\tGame.EndDlgBranch(\"DIALOG_{3}_{0}_{1}_{2:D2}\");",m_Dialog.PlayerActor,m_Dialog.RespondingActor,ID,m_Dialog.Scene);
			output2.AppendLine("");
			
			output2.AppendLine("\n\tSelected = Game.GetResponse();");
			output2.AppendLine("\tswitch(Selected) {");
			output2.AppendLine("");
			
			output2.Append(output3);
			output2.AppendLine("\tdefault:");
			output2.AppendLine("\t\tDEBUG(\"Error!! in switch\");");
			output2.AppendLine("\t}\n");
			
			if (Loop) {
				output2.AppendLine("\t}");
			}
			
			output2.AppendLine("}");
			
			output2.Append(output5);
		}

		// todo , use the choicebox array and use one function instead of 4.
		void ChoiceBox1TextChanged(object sender, EventArgs e)
		{
			ChoiceboxTextChanges(0);
		}
		
		
		void ChoiceBox2TextChanged(object sender, System.EventArgs e)
		{
			ChoiceboxTextChanges(1);
		}
		
		
		void ChoiceBox3TextChanged(object sender, System.EventArgs e)
		{
			ChoiceboxTextChanges(2);
		}
		
		
		void ChoiceBox4TextChanged(object sender, System.EventArgs e)
		{
			ChoiceboxTextChanges(3);
		}
		
		void ChoiceBox1FocusEnter(object sender, EventArgs e)
		{
			focusChoice(0);
		}
		
		
		void ChoiceBox2FocusEnter(object sender, EventArgs e)
		{
			focusChoice(1);
		}
		
		void ChoiceBox3FocusEnter(object sender, EventArgs e)
		{
			focusChoice(2);
		}
		
		void ChoiceBox4FocusEnter(object sender, EventArgs e)
		{
			focusChoice(3);
		}
		
		
		
		void PlayerActorTextChanged(object sender, EventArgs e)
		{
			m_Dialog.PlayerActor = PlayerActorBox.Text;
		}
		
		void RespondingActorTextChanged(object sender, EventArgs e)
		{
			m_Dialog.RespondingActor = RespondingActorBox.Text;
		}
		
		void SceneTextChanged(object sender, EventArgs e)
		{
			m_Dialog.Scene = SceneBox.Text;
		}
		
		void Button3Click(object sender, EventArgs e)
		{
			ExportToWME();
		}
		
		
		void treeView1Clicked(object sender, EventArgs e)
		{			
//			if (treeView1.SelectedNode.Name != IDBox.Text)
				UpdateDialogFields(IDBox.Text);
		}
		
		void listViewResponseEdited(object sender, LabelEditEventArgs e)
		{
		  // Determine if label is changed by checking for null.
		   if (e.Label == null)
		      return;
		   
			int num =e.Item;
			Dialog.ResponseCollection col = (Dialog.ResponseCollection)m_responsesTable[m_CurrentResponseID];
			Dialog.Response response = col[num/2];
			
			//maybe have a better definition ?
			if (num % 2 == 0) {
				response.TalkString = e.Label.ToString();
			} else {
				response.ResponseString= e.Label.ToString();
			}
			
			TreeNode tNode = treeView1.Nodes.Find(m_CurrentResponseID,true)[0];
			tNode.Nodes[num].Text = e.Label.ToString();
			
			//InitTree();
		}
		
		void listViewBeforeResponseEdited(object sender, LabelEditEventArgs e)
		{
		   
		   int num = e.Item;			
		   string firstText = "";
		   Dialog.DialogChoice  dialogChoice = (Dialog.DialogChoice) m_ChoicesTable[m_CurrentResponseID];
			   
			if (num == listView1.Items.Count - 1) {
				Dialog.ResponseCollection col = (Dialog.ResponseCollection)m_responsesTable[m_CurrentResponseID];
				if (col == null) {
					col = new Dialog.ResponseCollection();
					m_responsesTable.Add(col,m_CurrentResponseID);
					dialogChoice.Response = col;		
					
				}
				
				if (num == 0)
					firstText = dialogChoice.SelectionString;
		   					
				
				TreeNode tNode = treeView1.Nodes.Find(m_CurrentResponseID,true)[0];
				TreeNode tNode1;
				
				
				Dialog.Response newRes = new Dialog.Response();
				int m = col.Add(newRes);
				col[m].TalkString  = firstText;
				
				if (col.Count > 1) {
					Dialog.Response oldRes = col[col.Count-2];
					newRes.BreakLoop = oldRes.BreakLoop;
					newRes.TargetIDSpecified = oldRes.TargetIDSpecified;
					if (newRes.TargetIDSpecified)
						newRes.TargetID = oldRes.TargetID;
				} else {
					tNode1 = tNode.Nodes.Add("<-");
					tNode1.ForeColor = Color.Purple;
					
				}
				
				listView1.Items[num].ForeColor = Color.Blue;				
				listView1.Items[num].Text = firstText;
				
				
				ListViewItem tItem = listView1.Items.Add("");				
				tItem.ForeColor = Color.Red;
				
				listView1.Items.Add("<NEW>");
				
				tNode1 = tNode.Nodes.Insert(num ,firstText);
				tNode1.ForeColor = Color.Blue;
				tNode1.Name = m_CurrentResponseID;
				
				tNode1 = tNode.Nodes.Insert(num +1,"");
				tNode1.ForeColor = Color.Red;
				tNode1.Name = m_CurrentResponseID;
				
				e.CancelEdit = true;
				listView1.Items[num].BeginEdit();
			}

		}
		
		void LoopCheckBoxCheckedChanged(object sender, EventArgs e)
		{
			if (IDBox.Text == "0") {
				m_Dialog.Loop = loopCheckBox.Checked;
			} else {
				((Dialog.DialogChoice)m_ChoicesTable[IDBox.Text]).Loop = loopCheckBox.Checked;
				breakLoopCheckBox.Enabled = loopCheckBox.Checked;
			}
			
				
		}
		
		
		void BreakLoopCheckBoxCheckedChanged(object sender, EventArgs e)
		{
			Dialog.ResponseCollection resCol = (Dialog.ResponseCollection) m_responsesTable[m_CurrentResponseID];
			resCol[resCol.Count -1].BreakLoop = breakLoopCheckBox.Checked;
			TreeNode tNode = treeView1.Nodes.Find(m_CurrentResponseID,true)[0];
			if (breakLoopCheckBox.Checked) {				
				bool found=false;
				foreach (TreeNode eNode in tNode.Nodes) {
					if (eNode.Text == "X")
						found = true;
				}
				if (!found) {
					TreeNode tNode1 = tNode.Nodes.Add("X");
					tNode1.ForeColor = Color.Purple;
					tNode1.Name = m_CurrentResponseID;
				}
				
			} else {
				foreach (TreeNode eNode in tNode.Nodes) {
					if (eNode.Text == "X") {
						tNode.Nodes.Remove(eNode);
						break;
					}
				}
				
			}
		}
		
		void OpenToolStripMenuItemClick(object sender, EventArgs e)
		{
			ButtonStringTablePathClick(sender,e);
		}
		
		void SaveToolStripMenuItemClick(object sender, EventArgs e)
		{
			ConsolidateTree(null);
			if (textBoxXMLFilePath.Text.Length != 0)
				SaveTree();
			else 			
				Button1Click( sender,  e);
			
		}
		
		void SaveAsToolStripMenuItemClick(object sender, EventArgs e)
		{
			
			Button1Click( sender,  e);
			

			
		}
		
		void ExportToolStripMenuItemClick(object sender, EventArgs e)
		{
			ExportToWME();
		}
		
		void AboutToolStripMenuItemClick(object sender, EventArgs e)
		{
			MessageBox.Show("Dialog Creation Tool\nMade for Wintermute Engine (WME)\n\nby Oded Sharon\nCorbomite Games\n\nAll Rights Reserved.\n");
		}
		
		void NewToolStripMenuItemClick(object sender, EventArgs e)
		{
			NewTree();
		}
		
		void ExitToolStripMenuItemClick(object sender, System.EventArgs e)
		{
			Form.ActiveForm.Close();
		}
		
		void TreeView1KeyDown(object sender, KeyEventArgs e)
		{
			if (e.KeyCode == Keys.Delete) {
				if (MessageBox.Show("There is no undo for now, ARE YOU SURE ?","Confirm Delete",MessageBoxButtons.YesNo,MessageBoxIcon.Warning,MessageBoxDefaultButton.Button2) != DialogResult.Yes)
					return;
				
				string thisID = treeView1.SelectedNode.Name;
				if (thisID == "0") {					
					NewTree();
					return;
				}
				string parent = treeView1.SelectedNode.Parent.Name;
				
				
				Dialog.DialogChoice parentChoice = (Dialog.DialogChoice)m_ChoicesTable[parent];
				Dialog.DialogChoice thisChoice   = (Dialog.DialogChoice)m_ChoicesTable[thisID];                                           
				parentChoice.DialogChoice1.Remove(thisChoice);
				InitTree();
				
				
			}
		}
		
		
		void TreeView1DragDrop(object sender, DragEventArgs e)
		{
			
			Point pt = treeView1.PointToClient(new Point (e.X,e.Y));
			TreeNode onNode = treeView1.GetNodeAt(pt);
			//MessageBox.Show("drop "  + e.Data.GetType().ToString() + " on : " + onNode.Name);
			
			TreeNode intNode = 	(TreeNode)e.Data.GetData("System.Windows.Forms.TreeNode");
			if (!DragValidityCheck(intNode,onNode)) {
				this.Refresh();
				return;
			}
			
			
			// update behind the backend dialog structure
			Dialog.DialogChoice parentChoice = (Dialog.DialogChoice )m_ChoicesTable[intNode.Parent.Name];
			Dialog.DialogChoice inChoice = (Dialog.DialogChoice )m_ChoicesTable[intNode.Name];
			Dialog.DialogChoice onChoice = (Dialog.DialogChoice )m_ChoicesTable[onNode.Name];
			
			
			if (onNode.Name == onNode.Parent.Name)
				onNode = onNode.Parent;
			
			//if (intNode.Parent == onNode) {// order change
				
			//} else {// regular add
			
				
				parentChoice.DialogChoice1.Remove(inChoice);
				onChoice.DialogChoice1.Add(inChoice);
				
				// upadate treeview
				/*
				 //if (this.NodeMap == "" || this.NodeMap == null)
				//	return;

				  
				TreeNode MovingNode = intNode;
		        string[] NodeIndexes = this.NodeMap.Split('|');
		        TreeNodeCollection InsertCollection = this.treeView1.Nodes;
		        for(int i = 0; i < NodeIndexes.Length - 1; i++)
		        {
		            InsertCollection = InsertCollection[Int32.Parse(
		               NodeIndexes[i])].Nodes;
		        }
		        if(InsertCollection != null)
		        {
		            InsertCollection.Insert(Int32.Parse(NodeIndexes[
		             NodeIndexes.Length - 1]), (TreeNode)MovingNode.Clone());
		            this.treeView1.SelectedNode = InsertCollection[
		             Int32.Parse(NodeIndexes[NodeIndexes.Length - 1])];
		            MovingNode.Remove();
		        }
				*/
				
				intNode.Remove();
				onNode.Nodes.Add(intNode);				
			//}
		}
		
		void TreeView1DragEnter(object sender, DragEventArgs e)
		{
			
			//MessageBox.Show("enter. " + " data: " + e.Data.GetType().ToString() + " effect: " + e.Effect.ToString());
			if (e.Data.GetDataPresent("System.Windows.Forms.TreeNode")) 
				e.Effect = DragDropEffects.Move;
	
		}
		
		void TreeView1ItemDrag(object sender, ItemDragEventArgs e)
		{
			string ID = treeView1.SelectedNode.Name;
			if (ID == "0" || ID == "" || ID == null) 
				return;	
			
			TreeNode tNode = (TreeNode) e.Item;
			if (tNode.Name == tNode.Parent.Name)
				return;
			if (treeView1.SelectedNode.Name == treeView1.SelectedNode.Parent.Name)
				return;
						    
			treeView1.SelectedNode = tNode; 
			treeView1.DoDragDrop(e.Item, DragDropEffects.All);
		}
		
		void TreeView1DragOver(object sender, DragEventArgs e)
		{
			Point pt = treeView1.PointToClient(new Point (e.X,e.Y));
			//MessageBox.Show("dragOver "  + e.Data.GetType().ToString() + " on : " + tNode.Name);
			
			
			TreeNode onNode = treeView1.GetNodeAt(pt);
			//MessageBox.Show("drop "  + e.Data.GetType().ToString() + " on : " + onNode.Name);
			
			TreeNode intNode = 	(TreeNode)e.Data.GetData("System.Windows.Forms.TreeNode");
			if (!DragValidityCheck(intNode,onNode)) {
				e.Effect = DragDropEffects.None;
				return;
			}
		
			
			e.Effect = DragDropEffects.Move;
			
			/*
			#region Store the placeholder info into a pipe delimited string
			Graphics g = this.treeView1.CreateGraphics();
			TreeNode NodeOver = onNode;
			TreeNode tnPlaceholderInfo = NodeOver;
			string NewNodeMap = ((int)NodeOver.Index).ToString();
			while(tnPlaceholderInfo.Parent != null)
			{
			    tnPlaceholderInfo = tnPlaceholderInfo.Parent;
			     NewNodeMap = tnPlaceholderInfo.Index + "|" + NewNodeMap;
			}
			if(NewNodeMap == this.NodeMap)
			    return;
			else
			    this.NodeMap = NewNodeMap;
			#endregion
			//while (NodeOver.Name == NodeOver.Parent.Name)
			//	NodeOver = NodeOver.Parent;
			#region Clear placeholders above and below
			this.Refresh();
			#endregion
			#region Draw the placeholders
			int LeftPos, RightPos;
			LeftPos = NodeOver.Bounds.Left;// - NodeOverImageWidth;
			RightPos = this.treeView1.Width - 4;
			Point[] LeftTriangle = new Point[5]{
			    new Point(LeftPos, NodeOver.Bounds.Top - 4), 
			    new Point(LeftPos, NodeOver.Bounds.Top + 4), 
			    new Point(LeftPos + 4, NodeOver.Bounds.Y), 
			    new Point(LeftPos + 4, NodeOver.Bounds.Top - 1), 
			    new Point(LeftPos, NodeOver.Bounds.Top - 5)};
			
			Point[] RightTriangle = new Point[5]{
			    new Point(RightPos, NodeOver.Bounds.Top - 4),
			    new Point(RightPos, NodeOver.Bounds.Top + 4),
			    new Point(RightPos - 4, NodeOver.Bounds.Y),
			    new Point(RightPos - 4, NodeOver.Bounds.Top - 1),
			    new Point(RightPos, NodeOver.Bounds.Top - 5)};
			
			g.FillPolygon(System.Drawing.Brushes.Black, LeftTriangle);
			g.FillPolygon(System.Drawing.Brushes.Black, RightTriangle);
			g.DrawLine(new System.Drawing.Pen(Color.Black, 2), 
			  new Point(LeftPos, NodeOver.Bounds.Top), 
			  new Point(RightPos, NodeOver.Bounds.Top));
			#endregion
			toolStripStatusLabel1.Text = 	"dragOver "  + e.Data.GetType().ToString() + " on : " + intNode.Name + " x: " + pt.X + " y:" + pt.Y + " nodemap: " + this.NodeMap; 
*/
		}
		
		bool DragValidityCheck(TreeNode intNode, TreeNode onNode)
		{
			//if (intNode.Parent == onNode)
			//	return false;
		
			for (TreeNode enumNode = onNode;enumNode != null; enumNode = enumNode.Parent) {
				if (enumNode == intNode) 
					return false; //the inNode is a parent of the onNode
			}
			
			Dialog.DialogChoice onChoice = (Dialog.DialogChoice)m_ChoicesTable[onNode.Name];
			if (onChoice.DialogChoice1.Count >= 4)
				return false;
			
			return true;
		}
		
		void TreeView1MouseClick(object sender, MouseEventArgs e)
		{
			//treeView1.SelectedNode = treeView1.GetNodeAt(e.Location);
			//toolStripStatusLabel1.Text = "selected = " + treeView1.SelectedNode.Name;			
		}
		

		
		void TreeView1MouseDown(object sender, MouseEventArgs e)
		{
			//treeView1.SelectedNode = treeView1.GetNodeAt(e.Location);
	//		if (treeView1.SelectedNode != null)
	//			toolStripStatusLabel1.Text = "selected = " + treeView1.SelectedNode.Name + " loc: " + e.Location.ToString() + " X: " + e.X  + " Y: " + e.Y;
	
		}
		
		void ListView1KeyDown(object sender, KeyEventArgs e)
		{
			if (e.KeyCode == Keys.Delete) {
				
				if (MessageBox.Show("There is no undo for now, ARE YOU SURE ?","Confirm Delete",MessageBoxButtons.YesNo,MessageBoxIcon.Warning,MessageBoxDefaultButton.Button2) != DialogResult.Yes)
					return;
				
				int number = listView1.SelectedIndices[0];
				
				
				//Dialog.DialogChoice parentChoice = (Dialog.DialogChoice)m_ChoicesTable[TargetIDBox];
				Dialog.ResponseCollection response   = (Dialog.ResponseCollection)m_responsesTable[m_CurrentResponseID];
				
				if (number > 1) {
					Dialog.Response responseToRemove   =  response[number/2];
					Dialog.Response responseBefore     =  response[(number-2)/2];
					responseBefore.BreakLoop = responseToRemove.BreakLoop;
					responseBefore.TargetIDSpecified = responseToRemove.TargetIDSpecified;
					if (responseToRemove.TargetIDSpecified)
						responseBefore.TargetID = responseToRemove.TargetID;
				}
								
				
				response.RemoveAt(number/2);
				
				InitTree();
				fillListBox(m_CurrentResponseID,IDBox.Text);
				
				
				
			} else {
				ListView.SelectedIndexCollection selected= listView1.SelectedIndices;
				if (selected != null && selected.Count > 0) {
					int number = selected[0];
					//listView1.Items[number].Text = listView1.Items[number].Text + e.;
					listView1.Items[number].BeginEdit();
				}
			}
		}
		
		void CheckBoxOnceCheckedChanged(object sender, EventArgs e)
		{			
			Dialog.DialogChoice current = (Dialog.DialogChoice)m_ChoicesTable[IDBox.Text];
			if (current == null)
				checkBoxOnce.Checked = false;
			else
				current.DisplayOnce = checkBoxOnce.Checked;
		}
		
		void TestButtonClick(object sender, EventArgs e)
		{
			string tmpPlayerActor = m_Dialog.PlayerActor;
			string tmpResponsingActor = m_Dialog.RespondingActor;
			
			m_Dialog.PlayerActor = "Actor1";
			m_Dialog.RespondingActor = "Actor2";
			
			
			// Get data fields from registry
            RegistryEditor ra = new RegistryEditor(REGISTRY_SUB_KEY, RegistryKeyPermissionCheck.ReadWriteSubTree);

            string wmeExeFile = ra.ReadRegistryKeyValue(REG_KEY_WME_EXEC, "");
            if (wmeExeFile == "") {
            		DialogResult dr = openFileWMEEXE.ShowDialog();
            		if (DialogResult.OK != dr)
            		{       
            			return;
		                
        		
            		}
            		wmeExeFile = openFileWMEEXE.FileName;
            		
            		ra.WriteRegistryKeyValue(REG_KEY_WME_EXEC,wmeExeFile);
            		
            }
            
            string wmeWPRFile = ra.ReadRegistryKeyValue(REG_KEY_WME_PROJECT, "");
            if (wmeWPRFile == "") {
            		DialogResult dr = openFileWpr.ShowDialog();
            		if (DialogResult.OK != dr)
            		{       
            			return;
		                
        		
            		}
            		wmeWPRFile = openFileWpr.FileName;
            		
            		ra.WriteRegistryKeyValue(REG_KEY_WME_PROJECT,wmeWPRFile);
            		
            }
            
            string dir = System.IO.Path.GetDirectoryName(wmeWPRFile);
            toolStripStatusLabel1.Text = dir;
            
            string stringtab = dir + "\\data\\string.tab";
            string script = dir + "\\data\\scenes\\front\\scr\\Dialog.script";
            
            ExportToWME2(script ,stringtab);
            
            System.Diagnostics.Process.Start(wmeExeFile,"-project \"" + wmeWPRFile + "\"");
			
			m_Dialog.PlayerActor = tmpPlayerActor;
			m_Dialog.RespondingActor = tmpResponsingActor;
			
		}
		
		
		
		void TestInWMEToolStripMenuItemClick(object sender, EventArgs e)
		{
			TestButtonClick(sender,e);
		}
	}
}

